package com.zhiwen.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhiwen.common.exception.BusinessException;
import com.zhiwen.domain.dto.AnswerDTO;
import com.zhiwen.domain.entity.Answer;
import com.zhiwen.domain.entity.Question;
import com.zhiwen.domain.entity.User;
import com.zhiwen.mapper.AnswerMapper;
import com.zhiwen.service.AnswerService;
import com.zhiwen.service.NotificationProducer;
import com.zhiwen.service.QuestionService;
import com.zhiwen.service.UserService;
import com.zhiwen.domain.vo.AnswerVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 回答服务实现类
 */
@Service
@RequiredArgsConstructor
public class AnswerServiceImpl extends ServiceImpl<AnswerMapper, Answer> implements AnswerService {

    private final UserService userService;
    private final QuestionService questionService;
    @Autowired
    private NotificationProducer notificationProducer;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AnswerVO createAnswer(AnswerDTO answerDTO) {
        // 获取当前登录用户
        Long userId = StpUtil.getLoginIdAsLong();

        // 查询问题是否存在
        Question question = questionService.getById(answerDTO.getQuestionId());
        if (question == null) {
            throw new BusinessException("问题不存在");
        }

        // 创建回答
        Answer answer = new Answer();
        BeanUtils.copyProperties(answerDTO, answer);

        // 设置回答初始值
        answer.setUserId(userId);
        answer.setIsAccepted(0);
        answer.setVoteCount(0);
        answer.setCommentCount(0);
        answer.setCreateTime(LocalDateTime.now());
        answer.setUpdateTime(LocalDateTime.now());

        // 保存回答
        boolean saved = this.save(answer);
        if (!saved) {
            throw new BusinessException("保存回答失败");
        }

        // 获取问题信息
        question = questionService.getById(answerDTO.getQuestionId());

        // 发送问题回答通知
        if (question != null && !question.getUserId().equals(userId)) {
            notificationProducer.sendQuestionAnsweredNotification(
                    answerDTO.getQuestionId(),
                    answer.getId(),
                    question.getUserId(), // 问题作者ID（接收者）
                    userId // 回答作者ID（发送者）
            );
        }

        // 增加问题回答数量
        question.setAnswerCount(question.getAnswerCount() + 1);
        question.setLastAnswerTime(LocalDateTime.now());
        questionService.updateById(question);

        return convertToVO(answer);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AnswerVO updateAnswer(AnswerDTO answerDTO) {
        // 获取当前登录用户
        Long userId = StpUtil.getLoginIdAsLong();

        // 查询回答
        Answer answer = getById(answerDTO.getId());
        if (answer == null) {
            throw new BusinessException("回答不存在");
        }

        // 检查权限（只有管理员或回答创建者可以修改）
        User user = userService.getById(userId);
        if (!userId.equals(answer.getUserId()) && user.getRole() != 3) {
            throw new BusinessException("无权限修改该回答");
        }

        // 更新回答
        answer.setContent(answerDTO.getContent());
        answer.setUpdateTime(LocalDateTime.now());

        // 保存回答
        updateById(answer);

        return convertToVO(answer);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAnswer(Long id) {
        // 获取当前登录用户
        Long userId = StpUtil.getLoginIdAsLong();

        // 查询回答
        Answer answer = getById(id);
        if (answer == null) {
            throw new BusinessException("回答不存在");
        }

        // 检查权限（只有管理员或回答创建者可以删除）
        User user = userService.getById(userId);
        if (!userId.equals(answer.getUserId()) && user.getRole() != 3) {
            throw new BusinessException("无权限删除该回答");
        }

        // 删除回答（逻辑删除）
        removeById(id);

        // 更新问题回答数量
        Question question = questionService.getById(answer.getQuestionId());
        if (question != null && question.getAnswerCount() > 0) {
            question.setAnswerCount(question.getAnswerCount() - 1);
            questionService.updateById(question);
        }
    }

    @Override
    public AnswerVO getAnswerDetail(Long id) {
        // 查询回答
        Answer answer = getById(id);
        if (answer == null || answer.getDeleted() == 1) {
            throw new BusinessException("回答不存在");
        }

        return convertToVO(answer);
    }

    @Override
    public Page<AnswerVO> getAnswerPage(Long questionId, Page<Answer> page) {
        // 构建查询条件
        LambdaQueryWrapper<Answer> wrapper = new LambdaQueryWrapper<>();

        // 问题ID条件
        wrapper.eq(Answer::getQuestionId, questionId);

        // 未删除条件
        wrapper.eq(Answer::getDeleted, 0);

        // 已采纳的排在前面，点赞数高的排在前面
        wrapper.orderByDesc(Answer::getIsAccepted);
        wrapper.orderByDesc(Answer::getVoteCount);
        wrapper.orderByDesc(Answer::getCreateTime);

        // 分页查询
        Page<Answer> answerPage = page(page, wrapper);

        // 转换结果
        List<AnswerVO> answerVOList = answerPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        // 构建返回结果
        Page<AnswerVO> answerVOPage = new Page<>();
        BeanUtils.copyProperties(answerPage, answerVOPage, "records");
        answerVOPage.setRecords(answerVOList);

        return answerVOPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void acceptAnswer(Long id) {
        // 获取当前登录用户
        Long userId = StpUtil.getLoginIdAsLong();

        // 查询回答
        Answer answer = getById(id);
        if (answer == null) {
            throw new BusinessException("回答不存在");
        }

        // 查询问题
        Question question = questionService.getById(answer.getQuestionId());
        if (question == null) {
            throw new BusinessException("问题不存在");
        }

        // 检查权限（只有问题创建者可以采纳回答）
        if (!userId.equals(question.getUserId())) {
            throw new BusinessException("只有问题创建者可以采纳回答");
        }

        // 取消之前采纳的回答
        LambdaQueryWrapper<Answer> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Answer::getQuestionId, question.getId());
        wrapper.eq(Answer::getIsAccepted, 1);
        List<Answer> acceptedAnswers = list(wrapper);

        for (Answer oldAnswer : acceptedAnswers) {
            oldAnswer.setIsAccepted(0);
            updateById(oldAnswer);
        }

        // 采纳当前回答
        answer.setIsAccepted(1);
        updateById(answer);

        // 更新问题状态为已解决
        question.setStatus(2); // 已解决
        questionService.updateById(question);

        // 发送回答被采纳通知
        if (!question.getUserId().equals(answer.getUserId())) {
            notificationProducer.sendAnswerAcceptedNotification(
                    question.getId(),
                    id,
                    answer.getUserId(), // 回答者ID（接收者）
                    question.getUserId() // 问题作者ID（发送者）
            );
        }

        // TODO: 给回答者增加积分
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void voteAnswer(Long id) {
        // 获取当前登录用户
        Long userId = StpUtil.getLoginIdAsLong();

        // 查询回答
        Answer answer = getById(id);
        if (answer == null) {
            throw new BusinessException("回答不存在");
        }

        // TODO: 检查用户是否已点赞

        // 增加点赞数
        answer.setVoteCount(answer.getVoteCount() + 1);
        updateById(answer);

        // TODO: 记录用户点赞信息
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelVote(Long id) {
        // 获取当前登录用户
        Long userId = StpUtil.getLoginIdAsLong();

        // 查询回答
        Answer answer = getById(id);
        if (answer == null) {
            throw new BusinessException("回答不存在");
        }

        // TODO: 检查用户是否已点赞

        // 减少点赞数
        if (answer.getVoteCount() > 0) {
            answer.setVoteCount(answer.getVoteCount() - 1);
            updateById(answer);
        }

        // TODO: 删除用户点赞记录
    }

    @Override
    public Page<AnswerVO> getUserAnswers(Long userId, Page<Answer> page) {
        // 构建查询条件
        LambdaQueryWrapper<Answer> wrapper = new LambdaQueryWrapper<>();

        // 指定用户的回答
        wrapper.eq(Answer::getUserId, userId);

        // 未删除
        wrapper.eq(Answer::getDeleted, 0);

        // 按时间排序
        wrapper.orderByDesc(Answer::getCreateTime);

        // 分页查询
        Page<Answer> answerPage = page(page, wrapper);

        // 转换结果
        Page<AnswerVO> answerVOPage = new Page<>();
        BeanUtils.copyProperties(answerPage, answerVOPage, "records");

        // 获取回答列表
        List<AnswerVO> records = new ArrayList<>();
        for (Answer answer : answerPage.getRecords()) {
            AnswerVO answerVO = convertToVO(answer);

            // 获取问题信息
            Question question = questionService.getById(answer.getQuestionId());
            if (question != null) {
                answerVO.setQuestionTitle(question.getTitle());
            }

            records.add(answerVO);
        }

        answerVOPage.setRecords(records);
        return answerVOPage;
    }

    /**
     * 获取所有回答列表（管理员使用）
     */
    @Override
    public Page<AnswerVO> getAllAnswers(Long questionId, Page<Answer> page) {
        // 构建查询条件
        LambdaQueryWrapper<Answer> wrapper = new LambdaQueryWrapper<>();

        // 如果指定了问题ID，则按问题ID筛选
        if (questionId != null) {
            wrapper.eq(Answer::getQuestionId, questionId);
        }

        // 未删除条件
        wrapper.eq(Answer::getDeleted, 0);

        // 排序：创建时间倒序
        wrapper.orderByDesc(Answer::getCreateTime);

        // 分页查询
        Page<Answer> answerPage = page(page, wrapper);

        // 转换结果
        List<AnswerVO> answerVOList = answerPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        // 构建返回结果
        Page<AnswerVO> answerVOPage = new Page<>();
        BeanUtils.copyProperties(answerPage, answerVOPage, "records");
        answerVOPage.setRecords(answerVOList);

        return answerVOPage;
    }

    /**
     * 转换为VO对象
     */
    private AnswerVO convertToVO(Answer answer) {
        AnswerVO answerVO = new AnswerVO();
        BeanUtils.copyProperties(answer, answerVO);

        // 设置用户信息
        User user = userService.getById(answer.getUserId());
        if (user != null) {
            answerVO.setUsername(user.getUsername());
            answerVO.setNickname(user.getNickname());
            answerVO.setAvatar(user.getAvatar());
            answerVO.setIsExpert(user.getRole() == 2);
        }

        return answerVO;
    }
}
